package com.yunwushanhe.student.handler;

import com.auth0.jwt.interfaces.DecodedJWT;
import com.yunwushanhe.student.Contants.CodeEnum;
import com.yunwushanhe.student.Contants.Constant;
import com.yunwushanhe.student.bean.JwtManager;
import com.yunwushanhe.student.bean.ret.Result;
import com.yunwushanhe.student.util.JwtUtil;
import com.yunwushanhe.student.util.ResponseUtil;
import com.yunwushanhe.student.util.UserBaseInfoUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Slf4j
public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("检测到需要验证的请求有: {}",request.getRequestURI());
        /*
         * axios对非简单的请求(比如:Content-Type:application/json)有时会
         * 通过options请求来判断服务端是否支持跨域
         */
        String method = request.getMethod();
        if(HttpMethod.OPTIONS.matches(method)){ //进入if代表准许跨域，不用被拦截
            log.error("允许跨域不用获取token进行验证，直接放行！");
            return true;
        }
        // 获取token
        String token = StringUtils.firstNonBlank(request.getHeader(HttpHeaders.AUTHORIZATION),
                                                request.getParameter(Constant.USER_TOKEN_KEY));
        if(StringUtils.isBlank(token)){
            log.error("获取token出现问题");
            ResponseUtil.responseJson(response, Result.fail(CodeEnum.AUTH_ERR));
            return false;
        }

        Result<DecodedJWT> verifyResult = JwtUtil.verify(token);
        if(!verifyResult.getSuccess()){
            log.error("验证token出现问题");
            ResponseUtil.responseJson(response, Result.fail(CodeEnum.AUTH_ERR));
            return false;
        }

        //从token中还原出放入的对象
        JwtManager jwtManager = JwtUtil.parse(verifyResult.getData(), JwtManager.class);
        if (jwtManager == null){
            log.error("解析token出现问题");
            ResponseUtil.responseJson(response, Result.fail(CodeEnum.AUTH_ERR));
            return false;
        }

        //把用户基本信息放入ThreadLocal
        UserBaseInfoUtil.saveUserInfo(jwtManager);
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        UserBaseInfoUtil.removeUserInfo();
    }
}
